import { MangaSite } from "../MangaSite";

export namespace ToNaRiYJ {
    export interface ISeriesInfo {
        id: string;
        thumbnailUri: string;
        title: string;
    }

    export interface ISinglePageBase {
        align: "left" | "right";
        screen: number;
    }

    export interface ISinglePageOtherLink extends ISinglePageBase {
        type: "other" | "link" | "backMatter";
    }

    export interface ISinglePageMain extends ISinglePageBase {
        type: "main";
        choJuGiga: string;
        contentEnd: string;
        contentStart: string;
        width: number;
        height: number;
        isGif: boolean;
        src: string;
    }

    export type ITonariJPObjSinglePage = ISinglePageOtherLink | ISinglePageMain;

    export interface PageStructure {
        readingDirection: "rtl" | "ltr";
        single: ITonariJPObjSinglePage[];
        spread: ITonariJPObjSinglePage[];
    }
    export interface ReadableProduct {
        pageStructure: PageStructure;
        number: number;
        hasPurchased: boolean;
        id: string;
        imageUrisDigest: string;
        isPublic: boolean;
        nextReadableProductUri: string;
        permalink: string;
        prevReadableProductUri: string;
        publishedAt: string;
        series: ISeriesInfo;
        skipDrm: string;
        title: string;
        toc: string;
        typeName: "episode";
    }
    export interface ITonariJPObjEntry {
        readableProduct: ReadableProduct;
    }

    export interface ImgItemInfo extends MangaSite.ImgItemInfo {
        width: number;
        height: number;
    }

}

export class ToNaRiYJ extends MangaSite {
    protected partWidth = 200;
    protected partHeight = 280;
    public drawPage(
        img: HTMLImageElement,
        position: MangaSite.TDrawPosition = "right",
        showPageIndexLen: number = 2
    ): this {
        if (!img.getAttribute("site-id")) {
            this.directDrawPage(img, position, showPageIndexLen);
            return this;
        }
        const { partWidth, partHeight }  = this;
        const maxX = Math.floor(img.width / partWidth);
        const maxY = Math.floor(img.height / partHeight);
        const canvas = this.canvas;
        const cWidth = canvas.width;
        const cHeight = canvas.height;
        const scale = Math.min(cWidth / 2 / (partWidth * maxX), cHeight / (partHeight * maxY));
        this.scale = scale;
        this.imgShowSize.width = partWidth * scale * maxX;
        this.imgShowSize.height = partHeight * scale * maxY;
        const pieceWidth = Math.round(partWidth * scale);
        const pieceHeight = Math.round(partHeight * scale);
        const offsetY = (cHeight - pieceHeight * maxY) / 2;
        let offsetX = (cWidth / 2 - pieceWidth * maxX);
        if (showPageIndexLen === 1) {
            offsetX = (cWidth - pieceWidth * maxX) / 2;
        } else {
            if (position === "right") {
                offsetX = cWidth / 2;
            }
        }
        if (position === "right") {
            offsetX -= 3;
        }
        for (let x = 0; x < maxX; x ++) {
            for (let y = 0; y < maxY; y ++) {
                const deviantX = y;
                const deviantY = x;
                this.drawer.drawImage(
                    img,
                    x * partWidth,
                    y * partHeight,
                    partWidth,
                    partHeight,
                    y * pieceWidth + offsetX - deviantX,
                    x * pieceHeight + offsetY - deviantY,
                    pieceWidth,
                    pieceHeight
                );
            }
        }
        return this;
    }

    public async getImgList(): Promise<ToNaRiYJ.ImgItemInfo[]> {
        const str = await this.getJSON();
        const obj = JSON.parse(str) as ToNaRiYJ.ITonariJPObjEntry;
        const info = this.articleInfo;
        return obj
            .readableProduct
            .pageStructure
            .spread
            .filter((item) => {
                return item.type === "main";
            }).sort((itemA, itemB) => {
                return itemA.screen - itemB.screen;
            }).map((item, index) => {
                const mainItem = item as ToNaRiYJ.ISinglePageMain;
                return {
                    imgIndex: (index + 1),
                    src: mainItem.src,
                    width: mainItem.width,
                    height: mainItem.height,
                    type: info.download_method,
                };
            });
    }
}
